import * as cc from "cc";
import { GuideData, GuideMaskType } from "../define/GuideData";
import VCGuide from "../vc/VCGuide";
import { ViewBase } from './../../../../framework/view/ViewBase';
import { ShowGuideData } from './../define/GuideData';
import ComGuideTips from "./components/ComGuideTips";
import HollowOut from "./components/HolloOut";
import TouchBlocker from "./components/TouchBlocker";

const { ccclass, property, menu } = cc._decorator;
@ccclass("ViewGuide")
@menu("GameView/ViewGuide")
export default class ViewGuide extends ViewBase {

    protected static prefabUrl: string = "game/prefab/mvc/guide/Guide";
    public static className: string = "ViewGuide"
    protected vc: VCGuide = null;

    @property(HollowOut)
    private hollowOut: HollowOut = null;
    @property(TouchBlocker)
    private touchBlocker: TouchBlocker = null;
    @property({ type: cc.Node, tooltip: "手节点" })
    public guideHand: cc.Node = null;
    @property({ type: cc.Node, tooltip: "引导界面逻辑" })
    private nodeTips: cc.Node = null;
    @property({ type: cc.Node, tooltip: "引导模块父节点" })
    private nodeGuide: cc.Node = null;
    @property({ type: cc.Prefab, tooltip: "引导界面逻辑预制体" })
    private prefabTips: cc.Prefab = null;

    @property({ tooltip: "手移动到目标点需要的时间" })
    public handMoveTime: number = 0.3;

    private comGuideTips: ComGuideTips = null;
    //生命周期：onInit(加载时只调一次)==>onOpen(每次showui时)==>onShow()==>onStart()==>onHide()==>onClose()
    /**只会在首次加载时调用一次，可以用于获取节点，绑定事件 */
    protected onInit() {
        super.onInit();
        const tips = cc.instantiate(this.prefabTips);
        this.comGuideTips = tips.getComponent(ComGuideTips);
        this.comGuideTips.init();
        tips.setParent(this.nodeTips)

        this.hollowOut.nodeSize(); // 将遮罩镂空设为节点大小
        this.passAll(); // 放行所有点击
    }

    /**每次打开UI前，onStart前,每次呼出前赋值传参的时候用 */
    protected onOpen() {
        super.onOpen();
    }

    /**开始动画播完 onShow之后*/
    protected onStart() {
        super.onStart();
    }

    /**关闭动画结束后 */
    protected onClose() {
        super.onClose();
    }

    /**update生命周期 */
    protected onUpdate(dt) {
    }

    public openGuide() {
        this.nodeGuide.active = true;
        this.hollowOut.nodeSize(); // 将遮罩镂空设为节点大小
        this.touchBlocker.blockAll(); // 屏蔽所有点击
        this.showHand(false);
        this.showTip(false);
    }

    public showHand(isShow: boolean, handScale: number = 1) {
        if (this.guideHand) {
            this.guideHand.active = isShow;
            this.guideHand.setScale(cc.v3(handScale, handScale, handScale));
        }
    }

    private showTip(isShow: boolean, data?: GuideData, worldPos?: cc.Vec3, callback?: () => void) {
        if (!this.comGuideTips) {
            return;
        }
        this.comGuideTips.showTips(isShow, data, worldPos, callback);
    }

    public showGuide(showGuideData: ShowGuideData): Promise<void> {
        this.openGuide();
        return new Promise<void>(async (resolve, reject) => {
            let worldPos = null;

            if (showGuideData.target) {
                let targetUiTrans = showGuideData.target.getComponent(cc.UITransform);
                let nodeUiTrans = this.node.getComponent(cc.UITransform);
                worldPos = targetUiTrans.convertToWorldSpaceAR(cc.Vec3.ZERO)
                let nodePos = nodeUiTrans.convertToNodeSpaceAR(worldPos);
                this.showHand(true, showGuideData.guideData.handScale);
                cc.tween(this.guideHand)
                    .to(this.handMoveTime, { position: cc.v3(nodePos.x, nodePos.y, nodePos.z) })
                    .start()

                switch (showGuideData.guideData.maskType) {
                    case GuideMaskType.Circle:
                        let radius = showGuideData.guideData.radius || targetUiTrans.width / 2
                        await this.hollowOut.circleTo(this.handMoveTime, cc.v2(nodePos.x, nodePos.y), radius, 2);

                        break;
                    case GuideMaskType.Rect:
                        let width = showGuideData.guideData.width || targetUiTrans.width + 10;
                        let height = showGuideData.guideData.height || targetUiTrans.height + 10;
                        await this.hollowOut.rectTo(this.handMoveTime, cc.v2(nodePos.x, nodePos.y), width, height, 5, 5);
                        break;
                    default:
                        break;
                }
            } else {
                showGuideData.target = this.node;
            }

            if (showGuideData.guideData.maskType == GuideMaskType.None && showGuideData.guideData.maskAll) {
                this.hollowOut.maskAll();
            }

            this.touchBlocker.passAll()
            const isShowTip = showGuideData.guideData.tips != null;
            this.showTip(isShowTip, showGuideData.guideData, worldPos, () => {
                this.showTip(false);
                this.passAll();
                showGuideData.callback && showGuideData.callback();
            });
            this.touchBlocker.setTarget(showGuideData.target, showGuideData.isPassClick, () => {
                this.showTip(false);
                this.passAll();
                showGuideData.callback && showGuideData.callback();
            }); // 设置可点击节点     
        })
    }

    /**放行所有点击 */
    public passAll() {
        if (this.hollowOut) {
            this.hollowOut.nodeSize(); // 将遮罩镂空设为节点大小
        }
        if (this.touchBlocker) {
            this.touchBlocker.passAll(); // 放行所有点击
        }
        this.showHand(false);
        this.showTip(false);
        this.nodeGuide.active = false;
    }

    //**屏蔽所有点击 */
    public blockAll() {
        this.nodeGuide.active = true;
        if (this.hollowOut) {
            this.hollowOut.nodeSize(); // 将遮罩镂空设为节点大小
        }
        if (this.touchBlocker) {
            this.touchBlocker.blockAll(); // 放行所有点击
        }

        this.showHand(false);
        this.showTip(false);
    }

}